package com.bes.bessdk.service.commandset;

import static com.bes.bessdk.service.checkcrc.CheckCrcConstants.OP_TOTA_CHECK_CRC_DATA;
import static com.bes.bessdk.service.checkcrc.CheckCrcConstants.OP_TOTA_CHECK_CRC_RSP;
import static com.bes.bessdk.service.commandset.CommandSetConstants.BATTREY_PERCENTAGE_RIGHT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_BATTERY_BOX;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_IN_EAR_DETECTION_RESULT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.BATTREY_PERCENTAGE_LEFT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_BATTERY_LEFT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_BATTERY_RIGHT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_BES_SPATIAL_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_BUTTON_SETTINGS_CONTROL;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_BUTTON_STATUS;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_CEVA_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_CURRENT_PRODUCT_MODEL;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_DOLBY_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_DOLBY_SWITCH_AND_PARAM;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_EQ_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_IN_EAR_DETECTION_RESULT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_IS_FIT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_MIMI_INTENSITY;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_MIMI_SET_PRESENT_RESULT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_MIMI_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_MIMI_TECH_LEVEL;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_MULTIPOINT_STATE;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_REGULATE_ANC;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_SPP_CONNECT_STATUS;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_START_OTA;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_SWITCH_ROLE;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_TWS_AND_MASTER_STATE;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_VERSION_CRC;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_RECEIVE_WD_PROMPT_RESULT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_BATTREY_PERCENTAGE;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_BES_SPATIAL_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_BUTTON_SETTINGS_CONTROL;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_CEAV_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_DOLBY_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_EARBUD_FIT_TEST;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_EQ_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_GET_BUTTON_STATE;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_GET_CURRENT_PRODUCT_MODEL;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_GET_SPP_CONNECT_STATUS;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_IN_EAR_DETECTION;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_MIMI_SWITCH;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_MULTIPOINT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_REGULATE_ANC;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_START_OTA;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_SWITCH_ROLE;
import static com.bes.bessdk.service.commandset.CommandSetConstants.COMMAND_SET_TYPE_TWS_STATUS;
import static com.bes.bessdk.service.commandset.CommandSetConstants.EARBUD_FIT_TEST_FIT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.GET_SPP_CONNECT_STATUS_CONNECT;
import static com.bes.bessdk.service.commandset.CommandSetConstants.IN_EAR_DETECTION_ALL;
import static com.bes.bessdk.service.commandset.CommandSetConstants.IN_EAR_DETECTION_WD_PROMTP;
import static com.bes.bessdk.service.commandset.CommandSetConstants.MULTIPOINT_RECEIVE;
import static com.bes.bessdk.service.commandset.CommandSetConstants.SWITCH_STATUS_GET;
import static com.bes.bessdk.service.commandset.CommandSetConstants.SWITCH_STATUS_OPEN;
import static com.bes.bessdk.service.commandset.CommandSetConstants.SWITCH_STATUS_SET_PARAM;
import static com.bes.bessdk.service.commandset.CommandSetConstants.SWITCH_STATUS_SET_PARAM_2;
import static com.bes.bessdk.service.commandset.CommandSetConstants.SWITCH_STATUS_SET_PARAM_GET_TECH_LEVEL;
import static com.bes.bessdk.service.customcmd.CustomCmdConstants.OP_TOTA_SET_CUSTOMER_CMD;

import android.util.Log;

import com.bes.bessdk.service.checkcrc.CheckCrcConstants;
import com.bes.bessdk.utils.ArrayUtil;
import com.bes.bessdk.utils.CmdInfo;

import java.util.ArrayList;
import java.util.List;

public class CommandSetCMD {
    private static byte curBatteryPer = 0x00;
    private static String isFit = "";
    private static byte[] buttonSettingResult = new byte[4];
    private static byte[] inEarDetectionResult = new byte[0];
    private static byte[] wdPromptResult = new byte[1];
    private static byte[] buttonStateResult = new byte[0];

    private static int isSppConnect = 2;//1 connect 2 disconnect

    private static String currentProductModel = "";

    private static byte curANCState = 0x00;
    private static byte curEQState = 0x00;
    private static byte curEQStateType = 0x00;
    private static byte[] curCustomEQ = new byte[7];

    private static byte curDolbyState = 0x00;
    private static byte curDolbyParamState = 0x00;

    private static byte curBesSpatialState = 0x00;
    private static byte curMimiState = 0x00;
    private static byte curMimiPresetSetState = 0x00;
    private static int curMimiTechLevel = 0;
    private static int curMimiIntensity = 0;

    private static byte curCEVAState = 0x00;
    private static byte curTWSState = 0x00;
    private static byte curMasterState = 0x00;
    private static byte curMultiPiontState = 0x00;
    private static byte[] curRoleSwitchMarkData = new byte[4];
    private static byte[] curRoleSwitchMarkData2 = new byte[4];


    static byte[] magicCode = new byte[]{0x42, 0x45, 0x53, 0x54};
    private static CmdInfo crc_rsp = new CmdInfo(CheckCrcConstants.OP_TOTA_CHECK_CRC_RSP, new byte[0]);
    private static CmdInfo crc_data = new CmdInfo(CheckCrcConstants.OP_TOTA_CHECK_CRC_DATA, new byte[0]);
    private static String crcAndVersionStr = "";

    public static byte[] getCrcCMD() {
        CmdInfo getCrcInfo = new CmdInfo(CheckCrcConstants.OP_TOTA_CHECK_CRC_DATA, magicCode);
        return getCrcInfo.toBytes();
    }
    public static byte[] getCurCommand(Byte cmdType, boolean hasType, Byte...type) {
        byte[] cmd;
        if (hasType == false) {
            cmd = new byte[]{cmdType};
        } else {
            cmd = ArrayUtil.byteMerger(new byte[]{cmdType}, getCurType(type));
        }
        CmdInfo lastCmd = new CmdInfo(OP_TOTA_SET_CUSTOMER_CMD, cmd);
        return lastCmd.toBytes();
    }

    public static byte[] getCurMimiSetPresent(byte[] data) {
        CmdInfo lastCmd = new CmdInfo(OP_TOTA_SET_CUSTOMER_CMD, data);
        return lastCmd.toBytes();
    }

    private static byte[] getCurType(Byte...type) {
        List<Byte> temp = new ArrayList<>();
        for (Byte b : type) {
            temp.add(b);
        }
        byte[] lastBytes = new byte[temp.size()];
        for (int i = 0; i < temp.size(); i ++) {
            lastBytes[i] = temp.get(i);
        }

        return lastBytes;
    }

    public static byte getCurBatteryPercent() {
        return curBatteryPer;
    }

    public static String getCurFitStatus() {
        return isFit;
    }

    public static byte[] getCurInEarDetectionResult() {
        return inEarDetectionResult;
    }
    public static byte[] getWdPromptResult() {
        return wdPromptResult;
    }

    public static int getCurSppConnectStatus() {
        return isSppConnect;
    }

    public static byte[] getCurButtonState() {
        return buttonStateResult;
    }

    public static String getCurrentProductModel() {
        return currentProductModel;
    }

    public static byte getCurANCState() {
        return curANCState;
    }

    public static byte getCurEQState() {
        return curEQState;
    }

    public static byte getCurEQStateType() {
        return curEQStateType;
    }
    public static byte[] getCurCustomEQ() {
        return curCustomEQ;
    }

    public static byte getCurDolbyState() {
        return curDolbyState;
    }

    public static byte getCurDolbyParamState() {
        return curDolbyParamState;
    }

    public static byte getCurBesSpatialState() {
        return curBesSpatialState;
    }

    public static byte getCurMimiState() {
        return curMimiState;
    }

    public static byte getCurMimiPresetSetState() {
        return curMimiPresetSetState;
    }


    public static byte getCurCEVAState() {
        return curCEVAState;
    }

    public static byte[] getButtonSettingResult() {
        return buttonSettingResult;
    }

    public static String getCrcAndVersionStr() {
        return crcAndVersionStr;
    }

    public static byte getCurTWSState() {
        return curTWSState;
    }

    public static byte getCurMultiPiontState() {
        return curMultiPiontState;
    }

    public static int getCurMimiTechLevel() {
        return curMimiTechLevel;
    }

    public static byte getCurMasterState() {
        return curMasterState;
    }

    public static int getCurMimiIntensity() {
        return curMimiIntensity;
    }

    public static byte[] getCurRoleSwitchMarkData() {
        return curRoleSwitchMarkData;
    }

    public static byte[] getCurRoleSwitchMarkData2() {
        return curRoleSwitchMarkData2;
    }

    public static int receiveData(byte[] data) {
        if (data.length > 4) {
            CmdInfo lastCmd = new CmdInfo(OP_TOTA_SET_CUSTOMER_CMD, new byte[0]);
            Log.i("TAG", "lastCmd: -------" + ArrayUtil.toHex(lastCmd.toBytes()));
            if (data[0] == lastCmd.toBytes()[0] && data[1] == lastCmd.toBytes()[1]) {
                if (data[6] == COMMAND_SET_TYPE_BUTTON_SETTINGS_CONTROL) {
                    System.arraycopy(data, 7, buttonSettingResult, 0, buttonSettingResult.length);
                    return COMMAND_SET_RECEIVE_BUTTON_SETTINGS_CONTROL;
                } else if (data[6] == COMMAND_SET_TYPE_BATTREY_PERCENTAGE) {
                    curBatteryPer = data[8];
                    byte curBatteryType = data[7];
                    if (curBatteryType == BATTREY_PERCENTAGE_LEFT) {
                        return COMMAND_SET_RECEIVE_BATTERY_LEFT;
                    } else if (curBatteryType == BATTREY_PERCENTAGE_RIGHT) {
                        return COMMAND_SET_RECEIVE_BATTERY_RIGHT;
                    }
                    return COMMAND_SET_RECEIVE_BATTERY_BOX;
                } else if (data[6] == COMMAND_SET_TYPE_EARBUD_FIT_TEST) {
                    boolean mResult = data[7] == EARBUD_FIT_TEST_FIT ? true : false;
                    boolean sResult = data[8] == EARBUD_FIT_TEST_FIT ? true : false;
                    isFit = "M->" + mResult + " " + "S->" + sResult;
                    return COMMAND_SET_RECEIVE_IS_FIT;
                } else if (data[6] == COMMAND_SET_TYPE_IN_EAR_DETECTION) {
                    if (data[7] == IN_EAR_DETECTION_ALL) {
                        inEarDetectionResult = new byte[5];
                    } else if (data[7] == IN_EAR_DETECTION_WD_PROMTP) {
                        wdPromptResult[0] = data[8];
                        return COMMAND_SET_RECEIVE_WD_PROMPT_RESULT;
                    } else {
                        inEarDetectionResult = new byte[3];
                    }
                    System.arraycopy(data, 7, inEarDetectionResult, 0, inEarDetectionResult.length);
                    Log.i("TAG", "inEarDetectionResult: -------" + ArrayUtil.toHex(inEarDetectionResult));
                    return COMMAND_SET_RECEIVE_IN_EAR_DETECTION_RESULT;
                } else if (data[6] == COMMAND_SET_TYPE_GET_SPP_CONNECT_STATUS) {
                    if (data[7] == GET_SPP_CONNECT_STATUS_CONNECT) {
                        isSppConnect = 1;
                    } else {
                        isSppConnect = 2;
                    }
                    return COMMAND_SET_RECEIVE_SPP_CONNECT_STATUS;
                } else if (data[6] == COMMAND_SET_TYPE_GET_BUTTON_STATE) {
                    int resultL = data.length - 7;
                    buttonStateResult = new byte[resultL];
                    System.arraycopy(data, 7, buttonStateResult, 0, resultL);
                    return COMMAND_SET_RECEIVE_BUTTON_STATUS;
                } else if (data[6] == COMMAND_SET_TYPE_GET_CURRENT_PRODUCT_MODEL) {
                    byte[] l = new byte[2];
                    System.arraycopy(data, 7, l, 0, 2);
                    int length = ArrayUtil.byte2int(l);
                    byte[] modelData = new byte[length];
                    System.arraycopy(data, 9, modelData, 0, length);
                    currentProductModel = ArrayUtil.toASCII(modelData);
                    return COMMAND_SET_RECEIVE_CURRENT_PRODUCT_MODEL;
                } else if (data[6] == COMMAND_SET_TYPE_REGULATE_ANC) {
                    curANCState = data[7];
                    return COMMAND_SET_RECEIVE_REGULATE_ANC;
                } else if (data[6] == COMMAND_SET_TYPE_EQ_SWITCH) {
                    curEQState = data[7];
                    if (data.length > 8) {
                        curEQStateType = data[8];
                    }
                    if (data.length > 15) {
                        System.arraycopy(data, 9, curCustomEQ, 0, 7);
                    }
                    return COMMAND_SET_RECEIVE_EQ_SWITCH;
                } else if (data[6] == COMMAND_SET_TYPE_DOLBY_SWITCH) {
                    curDolbyState = data[7];
                    if (curDolbyState == SWITCH_STATUS_OPEN && data.length > 8) {
                        curDolbyParamState = data[8];
                        return COMMAND_SET_RECEIVE_DOLBY_SWITCH_AND_PARAM;
                    }
                    return COMMAND_SET_RECEIVE_DOLBY_SWITCH;
                } else if (data[6] == COMMAND_SET_TYPE_BES_SPATIAL_SWITCH) {
                    curBesSpatialState = data[7];
                    return COMMAND_SET_RECEIVE_BES_SPATIAL_SWITCH;
                } else if (data[6] == COMMAND_SET_TYPE_MIMI_SWITCH) {
                    if (data[7] == SWITCH_STATUS_SET_PARAM_GET_TECH_LEVEL) {
                        curMimiTechLevel = ArrayUtil.bytesToIntLittle(new byte[]{data[11], data[10], data[9], data[8]});
                        return COMMAND_SET_RECEIVE_MIMI_TECH_LEVEL;
                    } else if (data[7] == SWITCH_STATUS_SET_PARAM_2) {
                        curMimiIntensity = data[8];
                        return COMMAND_SET_RECEIVE_MIMI_INTENSITY;
                    } else if (data[7] == SWITCH_STATUS_SET_PARAM) {
                        curMimiPresetSetState = data[8];
                        return COMMAND_SET_RECEIVE_MIMI_SET_PRESENT_RESULT;
                    } else if (data[7] == SWITCH_STATUS_GET) {
                        curMimiState = data[8];
                        return COMMAND_SET_RECEIVE_MIMI_SWITCH;
                    }
                } else if (data[6] == COMMAND_SET_TYPE_CEAV_SWITCH) {
                    curCEVAState = data[7];
                    return COMMAND_SET_RECEIVE_CEVA_SWITCH;
                } else if (data[6] == COMMAND_SET_TYPE_START_OTA) {
                    return COMMAND_SET_RECEIVE_START_OTA;
                } else if (data[6] == COMMAND_SET_TYPE_TWS_STATUS) {
                    curTWSState = data[7];
                    curMasterState = data[8];
                    return COMMAND_SET_RECEIVE_TWS_AND_MASTER_STATE;
                } else if (data[6] == COMMAND_SET_TYPE_MULTIPOINT) {
                    if (data[7] == MULTIPOINT_RECEIVE) {
                        curMultiPiontState = data[8];
                        return COMMAND_SET_RECEIVE_MULTIPOINT_STATE;
                    }
                } else if (data[6] == COMMAND_SET_TYPE_SWITCH_ROLE) {
                    curRoleSwitchMarkData[0] = 0x03;
                    curRoleSwitchMarkData[1] = (byte) 0xff;
                    curRoleSwitchMarkData[2] = data[7];
                    curRoleSwitchMarkData[3] = data[8];

                    curRoleSwitchMarkData2[0] = 0x03;
                    curRoleSwitchMarkData2[1] = (byte) 0xff;
                    curRoleSwitchMarkData2[2] = data[9];
                    curRoleSwitchMarkData2[3] = data[10];
                    return COMMAND_SET_RECEIVE_SWITCH_ROLE;
                }
            } else if (crc_data.toBytes()[0] == data[0] && crc_data.toBytes()[1] == data[1]) {
                byte[] crc = new byte[4];
                System.arraycopy(data, 10 + 0 - 4, crc, 0 , 4);
                byte[] version = new byte[4];
                System.arraycopy(data, 10 + 0 + 4 - 4, version, 0 , 4);
                byte[] buildData = new byte[32];
                System.arraycopy(data, 10 + 0 + 4 + 4 - 4, buildData, 0 , 32);

                String crcStr = ArrayUtil.toHex(crc).replace(",", "");
                String versionStr = ArrayUtil.toHex(version).replace(",", ".");
                String buildDataStr = ArrayUtil.toASCII(buildData).replace("-", " ");
                crcAndVersionStr = "CRC: 0x" + crcStr + "\n"
                        + "Version: " + versionStr + "\n"
                        + "Build Data: " + buildDataStr;
                return COMMAND_SET_RECEIVE_VERSION_CRC;
            }
        }
        return 0;
    }
}